package device_center.conf.swagger;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        //http://ip地址:端口/项目名/swagger-ui.html#/
        ApiInfo apiInfo = new ApiInfoBuilder()
                //网站标题
                .title("Emm通用设备管理平台")
                //网站描述
                .description("移动安全管理平台是集移动设备管理、移动应用管理、移动文档管理、安全合规管理于一体的移动安全管理系统,可从用户、设备、应用、文档四个维度高效管理移动端的安全风险,是功能完整、能够快速实施落地的移动安全管理产品。")
                //版本
                .version("1.0")
                //联系人
                .contact(new Contact("Ezio.Auditore", "", ""))
                //协议
                .license("")
                //协议url
                .licenseUrl("")
                .build();

        //swagger版本
        return new Docket(DocumentationType.SWAGGER_2)
                .pathMapping("/")
                .select()
                //扫描那些controller
                .apis(RequestHandlerSelectors.basePackage("device_center"))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(apiInfo).securitySchemes(securitySchemes())
                .securityContexts(securityContexts())
                ;
    }


    /**
     * 通过Swagger2的securitySchemes配置全局参数：
     * 如下列代码所示，
     * securitySchemes的ApiKey中增加一个名为“Authorization”，
     * type为“header”的参数。
     *
     * @return
     */
    private List<ApiKey> securitySchemes() {
        ArrayList arrayList = new ArrayList();
        arrayList.add(new ApiKey("Bearer Token", "Bearer Token", "header"));
        return arrayList;
    }

    /**
     * 在Swagger2的securityContexts中通过正则表达式，
     * 设置需要使用参数的接口（或者说，是去除掉不需要使用参数的接口），
     * 如下列代码所示，通过PathSelectors.regex("^(?!auth).*$")，
     * 所有包含"auth"的接口不需要使用securitySchemes。
     * 即不需要使用上文中设置的名为“Authorization”，type为“header”的参数。
     *
     * @return
     */
    private List<SecurityContext> securityContexts() {
        ArrayList arrayList = new ArrayList();
        arrayList.add(SecurityContext.builder()
                .securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex("^(?!auth).*$"))
                .build());
        return arrayList;
    }

    /**
     * 设置完成后进入SwaggerUI，右上角出现“Authorization”按钮，点击即可输入我们配置的参数。
     * 对于不需要输入参数的接口（上文所述的包含auth的接口），在未输入Authorization参数就可以访问。
     * 其他接口则将返回401错误。点击右上角“Authorization”按钮，输入配置的参数后即可访问。参数输入后全局有效，无需每个接口单独输入。
     *
     * @return
     */
    List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        ArrayList arrayList = new ArrayList();
        arrayList.add(new SecurityReference("Authorization", authorizationScopes));
        return arrayList;
    }
}